
#include <ostream>
#include <exception>
#include <Geex/graphics/geexapp.h>
#include <Geex/basics/file_system.h>
#include <glut_viewer/tweak_bar.h>
#include <CGAL/Timer.h>
#include <cstdlib>
#include <ctime>
#include "nesting_aggregator.h"
#include "overlap.h"

namespace Nesting {
		
	using namespace Geex;

	void TW_CALL tw_opt_place(void *clientData);
	void TW_CALL tw_shrink_bdbox(void *clientData);
	//void TW_CALL tw_feature_set_callback(const void*, void *);
	//void TW_CALL tw_feature_get_callback(void*, void*);
	//void TW_CALL tw_curvature_get_callback(void*, void*);
	//void TW_CALL tw_curvature_set_callback(const void*, void*);

	
    class Nesting_application : public GeexApp 
	{
    public:
        Nesting_application(int argc, char** argv) : GeexApp(argc, argv) 
		{ 
            
			hdr_ = false ;
  
			tile_filename = get_file_arg("txt");

			sf = 0.01;
		}

        Nesting_aggregator* nesting_context() { return static_cast<Nesting_aggregator*>(scene()) ; }

        void init_scene() 
		{
            scene_ = new Nesting_aggregator(tile_filename);
        }

		void opt_place()
		{
			nesting_context()->find_nonoverlap_pos();
			glut_viewer_redraw();
		}
    
		void shrink_bdbox()
		{
			//double sf = 0.98;
			nesting_context()->shrink_bdbox(1-sf);
			glut_viewer_redraw();
		}
        void init_gui() 
		{
            GeexApp::init_gui() ;
			
            TwBar* graphics_bar = TwNewBar("Graphics");
			TwDefine("Graphics position='16 10' size='200 100' alpha=200"); 
			TwAddVarRW(graphics_bar, "Container", TW_TYPE_BOOL8, &nesting_context()->toggle_container(), "");
			TwAddVarRW(graphics_bar, "Bounding Box", TW_TYPE_BOOL8, &nesting_context()->toggle_bounding_box(), "");
			TwAddVarRW(graphics_bar,"Highlight", TW_TYPE_INT32, &nesting_context()->set_highlight_no(), "");
			
			TwBar* function_bar = TwNewBar("Functions");
			TwDefine("Functions position='216 10' size='200 100' alpha=200");
			//TwAddVarRW(function_bar, "Find", TW_TYPE_INT32, &tw_opt_place, "min=1");
			TwAddButton(function_bar, "Find", tw_opt_place, NULL, "key=f");
			TwAddButton(function_bar, "Press", tw_shrink_bdbox, NULL, "key=p");
			TwAddVarRW(function_bar, "Factor", TW_TYPE_DOUBLE, &sf, "min=0.00 max=0.03");
			toggle_skybox_CB() ;
            glut_viewer_add_toggle('b', glut_viewer_is_enabled_ptr(GLUT_VIEWER_BACKGROUND), "switch Color/BW") ;
            glut_viewer_add_toggle('v', &viewer_properties_->visible(), "viewer properties") ;
        }

    private:
        std::string tile_filename ;
		double sf;
     
    } ;


Nesting::Nesting_application* nesting_app() { return static_cast<Nesting::Nesting_application*>(Geex::GeexApp::instance()) ; }

void TW_CALL tw_opt_place(void *clientData) { nesting_app()->opt_place(); }
void TW_CALL tw_shrink_bdbox(void *clientData) { nesting_app()->shrink_bdbox(); }
//void TW_CALL tw_feature_set_callback(const void* fc, void *clientData) 
//{ 
//	spm_app()->feature_set_callback(*(double*)fc); 
//}
//void TW_CALL tw_feature_get_callback(void *value, void *clientData) 
//{ 
//	spm_app()->feature_get_callback((double*)value); 
//}
//void TW_CALL tw_curvature_get_callback(void *value, void *clientData)
//{
//	spm_app()->curvature_get_callback((double*)value);
//}
//void TW_CALL tw_curvature_set_callback(const void *value, void *clientData)
//{
//	spm_app()->curvature_set_callback(*(double*)value);
//}
}

int main(int argc, char** argv) 
{

	try 
	{
		Geex::initialize();
		Nesting::Nesting_application app(argc, argv) ;
		app.main_loop() ;
		Geex::terminate() ;
	}
	catch(std::exception& e)
	{
		std::cerr<<"Exception thrown : "<<e.what()<<std::endl;
#ifdef _DEBUG
		system("pause");
#endif
	}
	catch(...)
	{
		std::cerr<<"Unknown exception thrown.\n";
#ifdef _DEBUG
		system("pause");
#endif
	}
	return 0;
}
